/// ZY_DRV_DISP_KEY_MCU582
#include "CH58x_common.h"
#include "zqm_global.h"
#include "zqm_module.h"

#ifdef ZY_DRV_DISP_KEY_MCU582 // ZY_DRV_DISP_KEY_MCU582

// general codec functions----------------------------------------------------------------------------------
// led char code table: {char, code}
	//   AAA
	//  F   B
	//  F   B
	//   GGG
	//  E   C
	//  E   C
	//   DDD  H
static const uint8_t led_char_code_table[][2] = {
							// MASK -------------- | HG FE DCBA |
	{(uint8_t)'0', 0x3f},	// '0' --  ABCDEF   -- |    11 1111 | --
	{(uint8_t)'1', 0x06},	// '1' --   BC      -- |        11  | --
	{(uint8_t)'2', 0x5b},	// '2' --  AB DE G  -- |  1  1 1 11 | --
	{(uint8_t)'3', 0x4f},	// '3' --  ABCD  G  -- |  1    1111 | --
	{(uint8_t)'4', 0x66},	// '4' --   BC  FG  -- |  1 1   11  | --
	{(uint8_t)'5', 0x6d},	// '5' --  A CD FG  -- |  1 1  11 1 | --
	{(uint8_t)'6', 0x7d},	// '6' --  A CDEFG  -- |  1 11 11 1 | --
	{(uint8_t)'7', 0x07},	// '7' --  ABC      -- |        111 | --
	{(uint8_t)'8', 0x7f},	// '8' --  ABCDEFG  -- |  1 11 1111 | --
	{(uint8_t)'9', 0x6f},	// '9' --  ABCD FG  -- |  1 1  1111 | --
	{(uint8_t)'A', 0x77},	// 'A' --  ABC EFG  -- |  1 11  111 | --
	{(uint8_t)'a', 0x77},	// 'A' --  ABC EFG  -- |  1 11  111 | --
	{(uint8_t)'B', 0x7c},	// 'b' --    CDEFG  -- |  1 11 11   | --
	{(uint8_t)'b', 0x7c},	// 'b' --    CDEFG  -- |  1 11 11   | --
	{(uint8_t)'C', 0x39},	// 'C' --  A  DEF   -- |    11 1  1 | --
	{(uint8_t)'c', 0x58},	// 'c' --     DE G  -- |  1  1 1    | --
	{(uint8_t)'D', 0x5e},	// 'd' --   BCDE G  -- |  1  1 111  | --
	{(uint8_t)'d', 0x5e},	// 'd' --   BCDE G  -- |  1  1 111  | --
	{(uint8_t)'E', 0x79},	// 'E' --  A  DEFG  -- |  1 11 1  1 | --
	{(uint8_t)'e', 0x79},	// 'E' --  A  DEFG  -- |  1 11 1  1 | --
	{(uint8_t)'F', 0x71},	// 'F' --  A   EFG  -- |  1 11    1 | --
	{(uint8_t)'f', 0x71},	// 'F' --  A   EFG  -- |  1 11    1 | --
	{(uint8_t)'H', 0x76},	// 'H' --   BC EFG  -- |  1 11  11  | --
	{(uint8_t)'i', 0x30},	// '1' --      EF   -- |    11      | --
	{(uint8_t)'L', 0x38},	// 'L' --     DEF   -- |    11 1    | --
	{(uint8_t)'n', 0x54},	// 'n' --    C E G  -- |  1  1  1   | --
	{(uint8_t)'o', 0x5c},	// 'o' --    CDE G  -- |  1  1 11   | --
	{(uint8_t)'P', 0x73},	// 'P' --  AB  EFG  -- |  1 11   11 | --
	{(uint8_t)'r', 0x50},	// 'r' --      E G  -- |  1  1      | --
	{(uint8_t)'S', 0x6d},	// 's' --  A C  FG  -- |  1 1   1 1 | --
	{(uint8_t)'s', 0x6d},	// 's' --  A C  FG  -- |  1 1   1 1 | --
    {(uint8_t)'T', 0x78},	// 'T' --  A   EF   -- |    11    1 | --
	{(uint8_t)'t', 0x78},	// 't' --     DEFG  -- |  1 11 1    | --
	{(uint8_t)'-', 0x40},	// '-' --        G  -- |  1         | --
	{(uint8_t)' ', 0x00},	// ' ' --        G  -- |            | --
	{(uint8_t)'/', 0x52},	// '/' --   B  E G  -- |  1  1   1  | --
	{(uint8_t)'Z', 0xff},	// 'Z' --  ABCDEFGH -- | 11 11 1111 | --
	{(uint8_t)'U', 0x3e},	// '0' --   BCDEF   -- |    11 111  | --
	{(uint8_t)'u', 0x3e},	// '0' --   BCDEF   -- |    11 111  | --
	{(uint8_t)'\'',0x02},	// ''' --   B       -- |        1   | --
	{(uint8_t)',', 0x04},	// ',' --    C      -- |       1    | --
};
// led icon code table: {dig, seg}, seg = 0 - not available in this type of diaplay module
const uint8_t led_icon_code_table[LED_ICON_NUM][2] = {
	{3, 0x01}, {3, 0x00}, {3, 0x04}, {3, 0x00},			// disp_item_comp, disp_item_hot, disp_item_defrost, disp_item_lp,
	{3, 0x00}, {3, 0x00}, {3, 0x08}, {3, 0x40},			// disp_item_lock, disp_item_alarm, disp_item_fan, disp_item_door,
	{3, 0x00}, {3, 0x80}, {3, 0x00}, {3, 0x00},			// disp_item_wifi, disp_item_4g, disp_item_battery, disp_item_bt,
    {3, 0x00}, {3, 0x00}, {1, 0x80}, {2, 0x80},  		// disp_item_drip, disp_item_x, disp_item_dot, disp_item_minus
};
extern char disp_buff[LED_ITEM_NUM][2];
uint8_t disp_memory[DISP_MEMORY_SIZE];	        // 百, 十, 个, ICON, 4位8段
char key0 = 0, key1 = 0, key2 = 0, key3 = 0;

// codec a display elements in the disp_buff to disp_memory
void LedCodecItem(disp_item_t item_no, uint8_t isOn)
{
	uint8_t code = 0;
	uint8_t dig = 0;
	// icon type items
	if (item_no < LED_ICON_NUM) {
		dig = led_icon_code_table[item_no][0];
		code = led_icon_code_table[item_no][1];
		isOn = (disp_buff[item_no][0]) ? isOn : 0;
	}
	// char type items
	else if (item_no < LED_ITEM_NUM) {
		dig = disp_item_d_start + (item_no - LED_ICON_NUM);
		for (int i = 0; i < (sizeof(led_char_code_table) / sizeof(led_char_code_table[0])); i++) {
			if (disp_buff[item_no][0] == led_char_code_table[i][0]) {
				code = led_char_code_table[i][1];
				break;
			}
		}
		disp_memory[dig] &= 0x80; // clear 0-6 seg buf, 保留第7 seg, 这可能是. 或者 - 等符号 .
	}
	if (code != 0) // code = 0 is not available
		disp_memory[dig] = (isOn) ? (disp_memory[dig] | code) : (disp_memory[dig] & (~code));
	return;
}

#ifndef ZQ_SIMULATOR
// M582 driver functions -----------------------------------------------------------------------------------------------
__HIGH_CODE
void DrvDispAndKey_2ms(void)
{
    const uint32_t drv_disp_dip[4] = { IO_DISP_DIP_1, IO_DISP_DIP_2, IO_DISP_DIP_3, IO_DISP_DIP_0 }; // 百, 十, 个, ICON, 4位8段
    static uint8_t disp_refresh_idx = 0;
    // static char key0 = 0, key1 = 0, key2 = 0, key3 = 0;
    uint8_t ret = 0;
    if (++disp_refresh_idx >= 4) disp_refresh_idx = 0;
    // clear display
    for (int k = 0; k < 4; k++)
        GPIOB_SetBits(drv_disp_dip[k]);
    // refresh next dig
    uint8_t seg = disp_memory[disp_refresh_idx];
    (seg & 0x01) ? GPIOB_ResetBits(IO_DISP_SEG_0) : GPIOB_SetBits(IO_DISP_SEG_0);
    (seg & 0x02) ? GPIOB_ResetBits(IO_DISP_SEG_1) : GPIOB_SetBits(IO_DISP_SEG_1);
    (seg & 0x04) ? GPIOB_ResetBits(IO_DISP_SEG_2) : GPIOB_SetBits(IO_DISP_SEG_2);
    (seg & 0x08) ? GPIOB_ResetBits(IO_DISP_SEG_3) : GPIOB_SetBits(IO_DISP_SEG_3);
    (seg & 0x10) ? GPIOB_ResetBits(IO_DISP_SEG_4) : GPIOB_SetBits(IO_DISP_SEG_4);
    (seg & 0x20) ? GPIOB_ResetBits(IO_DISP_SEG_5) : GPIOB_SetBits(IO_DISP_SEG_5);
    (seg & 0x40) ? GPIOB_ResetBits(IO_DISP_SEG_6) : GPIOB_SetBits(IO_DISP_SEG_6);
    (seg & 0x80) ? GPIOB_ResetBits(IO_DISP_SEG_7) : GPIOB_SetBits(IO_DISP_SEG_7);
    GPIOB_ResetBits(drv_disp_dip[disp_refresh_idx]);
    // 刷新key, 连续读到10ms(5次)判断key down
    key0 = (GPIOB_ReadPortPin(IO_KEY_0)) ? 0 : ((key0 < 5) ? (key0 + 1) : key0);
    key1 = (GPIOB_ReadPortPin(IO_KEY_1)) ? 0 : ((key1 < 5) ? (key1 + 1) : key1);
    key2 = (GPIOB_ReadPortPin(IO_KEY_2)) ? 0 : ((key2 < 5) ? (key2 + 1) : key2);
    key3 = (GPIOB_ReadPortPin(IO_KEY_3)) ? 0 : ((key3 < 5) ? (key3 + 1) : key3);
    return;
}

// Display and key driver functions----------------------------------------------------------------------------------
void DrvDispKeyInit(void)
{
    // init display io
    GPIOB_ModeCfg(IO_DISP_DIP_0, GPIO_ModeOut_PP_20mA); //LED DIP1 
    GPIOB_ModeCfg(IO_DISP_DIP_1, GPIO_ModeOut_PP_20mA); //LED DIP2 
    GPIOB_ModeCfg(IO_DISP_DIP_2, GPIO_ModeOut_PP_20mA);//LED DIP3 
    GPIOB_ModeCfg(IO_DISP_DIP_3, GPIO_ModeOut_PP_20mA);//LED DIP4 
    GPIOB_SetBits(IO_DISP_DIP_0);
    GPIOB_SetBits(IO_DISP_DIP_1);
    GPIOB_SetBits(IO_DISP_DIP_2);
    GPIOB_SetBits(IO_DISP_DIP_3);
    GPIOB_ModeCfg(IO_DISP_SEG_0, GPIO_ModeOut_PP_5mA);//SEG0
    GPIOB_ModeCfg(IO_DISP_SEG_1, GPIO_ModeOut_PP_5mA);//SEG1
    GPIOB_ModeCfg(IO_DISP_SEG_2, GPIO_ModeOut_PP_5mA);//SEG2
    GPIOB_ModeCfg(IO_DISP_SEG_3, GPIO_ModeOut_PP_5mA);//SEG3
    GPIOB_ModeCfg(IO_DISP_SEG_4, GPIO_ModeOut_PP_5mA);//SEG4
    GPIOB_ModeCfg(IO_DISP_SEG_5, GPIO_ModeOut_PP_5mA);//SEG5
    GPIOB_ModeCfg(IO_DISP_SEG_6, GPIO_ModeOut_PP_5mA);//SEG6
    GPIOB_ModeCfg(IO_DISP_SEG_7, GPIO_ModeOut_PP_5mA);//SEG7
    // init key io
    GPIOB_ModeCfg(IO_KEY_3, GPIO_ModeIN_PU); //KEY3
    GPIOB_ModeCfg(IO_KEY_2, GPIO_ModeIN_PU); //KEY2
    GPIOB_ModeCfg(IO_KEY_0, GPIO_ModeIN_PU); //KEY0
    GPIOB_ModeCfg(IO_KEY_1, GPIO_ModeIN_PU); //KEY1
   	memset(disp_memory, 0, DISP_MEMORY_SIZE);
	ZQLOG("m582 display and key scan init...");
}
// display 4-digit * 8-seg, brightness Level 0-7
void DrvDisplay(uint8_t brightness)
{
    return;
}
// Key Functions -----------------------------------------------------------------------------------------------
// return 2 key, bit1 = key1...bit0 = key2, 
uint8_t DrvReadKeys(void)
{
    uint8_t key = 0;
    if (key0 >= 5) key |= 0x01;
    if (key1 >= 5) key |= 0x02;
    if (key2 >= 5) key |= 0x08;
    if (key3 >= 5) key |= 0x04;

    if (dbg_key != 0)  // 有dbg模拟key产生, 优先处理
        return dbg_key;
    else
        return key;
}


#endif // ZQ_SIMULATOR
#endif // ZY_DRV_DISP_KEY_MCU582
